AWS Batch で EC2 スポットインスタンスを使った料金節約ができるかチュートリアルを試してみた
こんにちは、アノテーション テクニカルサポートチームの中野です。
読んでないのに新たに本を買って、散財してしまう生活をやめたいです。
今回は、AWS Batch でスポットインスタンスの動きを理解するために、公式のチュートリアルを試してみました。
チュートリアル
試したチュートリアルは以下の内容です。
30 分程度の時間を要しました。
結論
- 今回の検証では、スポットインスタンスによる 73 %のコスト削減ができた
やってみた
前提条件
前提として、AWS アカウントで EC2 スポットインスタンスを使用するために以下の 3 つの IAM ロールが必要です。
- AmazonEC2SpotFleetTaggingRole
- AWSServiceRoleForEC2Spot
- AWSServiceRoleForEC2SpotFleet
AmazonEC2SpotFleetTaggingRole は、ユーザの代わりにインスタンスの起動や終了などを行う権限をスポットフリーとに対して付与するためのロールです。
AWSServiceRoleForEC2Spot と AWSServiceRoleForEC2SpotFleet は、Amazon EC2 スポットおよびスポットフリートにサービスにリンクされたロールです。
なお、ここで注意点として、チュートリアル上は AmazonEC2SpotFleetTaggingRole ではなく、AmazonEC2SpotFleetRole を作成するように記載されています。しかし、AWS Batch のドキュメントには AmazonEC2SpotFleetRole は過去に使われていたマネージドポリシーということが書かれています。
AmazonEC2SpotFleetRole: これは、スポットフリートロール用の元のマネージドポリシーです。ただし、これを AWS Batch と一緒に使用することは推奨されなくなりました。
そのため、今回は新しいマネージドポリシーである AmazonEC2SpotFleetTaggingRole を利用します。
それでは、以下の手順で各ロールを作成してみます。
0-1. EC2 スポットフリートコンピューティング環境用の IAM ロールの作成
まず、AmazonEC2SpotFleetTaggingRole という IAM ロールを作成します。
$ aws iam create-role --role-name AmazonEC2SpotFleetTaggingRole \ --assume-role-policy-document '{"Version":"2012-10-17","Statement":[{"Sid":"","Effect":"Allow","Principal":{"Service":"spotfleet.amazonaws.com"},"Action":"sts:AssumeRole"}]}' { "Role": { "Path": "/", "RoleName": "AmazonEC2SpotFleetTaggingRole", "RoleId": "ARO**************", "Arn": "arn:aws:iam::************:role/AmazonEC2SpotFleetTaggingRole", "CreateDate": "2022-02-01T07:05:08Z", "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Sid": "", "Effect": "Allow", "Principal": { "Service": "spotfleet.amazonaws.com" }, "Action": "sts:AssumeRole" } ] } } }
0-2. マネージド IAM ポリシー AmazonEC2SpotFleetTaggingRole を IAM ロールへアタッチ
マネージドポリシーである AmazonEC2SpotFleetTaggingRole を、先程作成した IAM ロールへアタッチします。
AmazonEC2SpotFleetTaggingRole は、ロールという名前がついていてややこしいですが、EC2 スポットインスタンスにタグを付けるために必要なアクセス権限を提供するポリシーです。
$ aws iam attach-role-policy \ --policy-arn arn:aws:iam::aws:policy/service-role/AmazonEC2SpotFleetTaggingRole \ --role-name AmazonEC2SpotFleetTaggingRole
0-3. EC2 スポット用の IAM Service-Linked Role の作成
EC2 スポット用の IAM の Service-Linked Role を作成します。
$ aws iam create-service-linked-role --aws-service-name spot.amazonaws.com { "Role": { "Path": "/aws-service-role/spot.amazonaws.com/", "RoleName": "AWSServiceRoleForEC2Spot", "RoleId": "ARO***************", "Arn": "arn:aws:iam::*************:role/aws-service-role/spot.amazonaws.com/AWSServiceRoleForEC2Spot", "CreateDate": "2022-02-01T07:05:28Z, "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Action": [ "sts:AssumeRole" ], "Effect": "Allow", "Principal": { "Service": [ "spot.amazonaws.com" ] } } ] } } }
0-4. EC2 スポットフリート用の IAM Service-Linked Role の作成
EC2 スポットフリートの IAM の Service-Linked Role を作成します。
$ aws iam create-service-linked-role --aws-service-name spotfleet.amazonaws.com { "Role": { "Path": "/aws-service-role/spotfleet.amazonaws.com/", "RoleName": "AWSServiceRoleForEC2SpotFleet", "RoleId": "ARO***************", "Arn": "arn:aws:iam::**************:role/aws-service-role/spotfleet.amazonaws.com/AWSServiceRoleForEC2SpotFleet", "CreateDate": "2022-02-01T07:07:33Z", "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Action": [ "sts:AssumeRole" ], "Effect": "Allow", "Principal": { "Service": [ "spotfleet.amazonaws.com" ] } } ] } } }
ステップ 1: EC2 スポットインスタンスを基盤とするコンピューティング環境を作成する
それでは、早速 EC2 スポットインスタンス用のコンピューティング環境を作成していきます。
なお、現在の AWS Batch のマネージメントコンソールは、チュートリアルのコンソールとデザインが若干異なっています。
コンピューティング環境作成画面で各種項目を入力していきます。
インスタンスの設定で「スポット」を選択します。 なお、AWS Batch では現在 Fargate も利用できるようになっておりますが、今回は EC2 インスタンスを利用します。
ここでは、デフォルトの VPC を利用するように選択します。
すべて選択が終わったら作成ボタンをクリックします。
作成後、コンピューティング環境がマネージメントコンソール上に表示されます。
ステップ 2: ジョブキューを作成する
次に、コンピューティング環境に接続するためのジョブキューを作成します。 優先度を 10 として、先程作成したコンピューティング環境を選択し、作成をクリックします。
ステップ 3: ジョブ定義を作成する
それでは、実際に AWS Batch でどういったジョブを実行させるか指定するために、ジョブ定義を作成します。 今回のジョブタイプは「単一ノード」にします。
実行ロールで、Fargate か EC2 か選択を聞かれるので、EC2 を選択します。 また、IAM ロールも作成した実行ロールを作成します。
次に、ジョブ内で実行されるコマンドを JSON 形式で定義します。 以下の様に、ジョブ内で自身のジョブ ID を取得して文字列として出力するように設定します。
["sh", "-c", "echo \"Hello world from job $AWS_BATCH_JOB_ID \".This is run attempt $AWS_BATCH_JOB_ATTEMPT"]
最後に、ジョブ定義を作成ボタンをクリックします。
ステップ 4: ジョブを実行して結果を確認する
では目的のジョブを実行してみましょう!!
ジョブセクションから、ジョブを送信ボタンをクリックして、ジョブを作成します。
作成が環境すると、ダッシュボードに移動してジョブの実行状況を観察します。 最初は「SUBMITTED」ですが、数分すると、「SUCCEEDED」に変化します。
「SUCCEEDED」 のステータスになったら、ジョブ実行のログを確認します。 以下の対象のジョブをクリックして表示した先の画面でログの詳細を確認できます。
画面したの「ログを取得」ボタンをクリックすると、権限の確認を聞かれるので「OK」を入力後、承認をクリックします。 その後、元の画面へリダイレクトされるとログが確認できます。
以下のように、文字列が出力されていれば成功です。
ステップ 5: 達成した節約を確認する
では、最後に、どの程度のスポットインスタンスによる節約ができたか、確認します。
ここで一旦、EC2 のマネージメントコンソールに移動します。
「削減の概要」をクリックすると、節約された結果が表示されます。
なんと、73%の節約に成功しました!やったー!
ステップ 6: リソースを削除する
チュートリアルは以上で終了です。お疲れさまでした。
最後に、不要なリソースの削除をやっておきます。
作成したジョブキューを無効化してから、削除します。
次に、コンピューティング環境も削除します。
ジョブキュー同様に無効化を行ってから、削除します。
削除するか最終確認のウィンドウがでてくるので、問題なければ削除ボタンをクリックします。
終わりです!
最後に
AWS Batch 自体の挙動を知る目的でチュートリアルを試してみましたが、スポットインスタンスについても触れることができて、なかなかよかったです。
ただし、AWS Batch の細かな設定による挙動については、もう少し公式ドキュメントを読みつつ、実際に動かしながら理解したほうがいいなともいました。
ので、いつかブログにしたいと思います(自戒を込めて)。
アノテーション株式会社について
アノテーション株式会社は、クラスメソッド社のグループ企業として「オペレーション・エクセレンス」を担える企業を目指してチャレンジを続けています。「らしく働く、らしく生きる」のスローガンを掲げ、様々な背景をもつ多様なメンバーが自由度の高い働き方を通してお客様へサービスを提供し続けてきました。現在当社では一緒に会社を盛り上げていただけるメンバーを募集中です。少しでもご興味あれば、アノテーション株式会社 WEB サイトをご覧ください。